package com.tydic.applet;

import com.tydic.deviceParse.COMConfig;
import com.tydic.deviceParse.LoadometerParser;
import com.tydic.exceptions.NoSuchPort;
import com.tydic.exceptions.PortInUse;
import com.tydic.exceptions.SerialPortParameterFailure;
import com.tydic.serialPort.SerialListener;
import com.tydic.serialPort.SerialPortManager;
import com.tydic.util.NumberUtil;
import gnu.io.SerialPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.applet.Applet;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Properties;

/**
 * Created by maliang on 2017/4/24.
 * 功能描述：
 * 1、通过该applet可以读取硬件端口信息
 */
public class DashboardApplet extends Applet implements Runnable {
    private final Logger logger = LoggerFactory.getLogger(DashboardApplet.class);
    //端口配置信息
    private COMConfig comConfig = COMConfig.getInstance();
    //从端口读取的数据
    public String portData = "0.00";
    //端口实例
    public SerialPort serialPort;
    //端口监听线程
    private Thread portListener;
    /**
     * 开启端口监听
     */
    public void init() {
        FileInputStream in = null;
        try {
            String destFilePath = System.getProperty("java.home").split(":")[0] + ":/loadometerParserConfig";
            destFilePath = destFilePath + "/comPortConfig.properties";
            Properties pro = new Properties();
            in = new FileInputStream(destFilePath);
            pro.load(in);
            comConfig.setPortname(pro.getProperty("PORTNAME"));
            comConfig.setBaudrate(Integer.parseInt(pro.getProperty("BAUDRATE")));
            comConfig.setDatabits(Integer.parseInt(pro.getProperty("DATABITS")));
            comConfig.setStopbits(Integer.parseInt(pro.getProperty("STOPBITS")));
            comConfig.setParity(Integer.parseInt(pro.getProperty("PARITY")));
            comConfig.setWeightIntStart(Integer.parseInt(pro.getProperty("WEIGHTINTSTART")));
            comConfig.setWeightIntEnd(Integer.parseInt(pro.getProperty("WEIGHTINTEND")));
            serialPort = SerialPortManager.openPort(comConfig);
            logger.info("插件初始化成功....");
        }catch (SerialPortParameterFailure e){
            logger.error(e.toString());
        }catch (NoSuchPort e){
            logger.error(e.toString());
        }catch (PortInUse e){
            logger.error(e.toString());
        }catch (Exception e) {
            logger.error("插件初始化失败,失败原因为："+e.getMessage());
        }finally {
            try{
                in.close();
            }catch (Exception e){
                logger.error(e.getMessage());
            }
        }
        resize(300, 260);

    }

    public void start() {
        if(serialPort == null){
            return;
        }
        try {
            logger.info("准备开始监听串口....");
            SerialPortManager.addListener(serialPort, new SerialListener(serialPort, this));
            logger.info("成功开始监听串口....");
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        portListener = new Thread(this);

        portListener.start();

    }

    /**
     * 绘制画面
     * @param g
     */
    public void paint(Graphics g) {
        String s1 = "电子地磅仪表盘（KG）";
        Font font = new Font("标题", Font.BOLD, 18);
        g.setColor(Color.CYAN);
        setBackground(Color.BLACK);
        g.setFont(font);
        g.drawString(s1, 20, 60);
        if(portData!=null){
            g.setColor(Color.yellow);
            g.setFont(new Font("标题", Font.BOLD, 28));
            g.drawString(portData, 20, 120);
        }
    }

    /**
     * 当调用repaint时，先清空画布的背景，否则，有闪烁或不更新画面的情况
     * @param g
     */
    public void update(Graphics g) {

        BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);

        Graphics2D gc = (Graphics2D) bi.getGraphics();

        gc.setColor(getBackground());

        gc.fillRect(0, 0, getWidth(), getHeight());

        paint(gc);

        gc.dispose();

        g.drawImage(bi, 0, 0, getWidth(), getHeight(), this);
    }

    public void stop() {
        //portListener = null;
        if(serialPort != null){
            portListener.stop();
            serialPort.removeEventListener();
            logger.info("关闭端口监听成功....");
        }
    }
   public void destroy(){
       logger.info("关闭窗口....");
       if(serialPort != null){
           SerialPortManager.closePort(serialPort);
           portListener.stop();
           serialPort.removeEventListener();
           logger.info("关闭串口成功....");
       }
   }

    public void run() {

        Thread currentThread = Thread.currentThread();

        while (currentThread == portListener) {
            byte[] readBuffer = new byte[20];
            try {
                int numBytes = -1;
                InputStream inputStream = serialPort.getInputStream();
                ArrayList<Double> dataCache = new ArrayList<Double>();
                while (inputStream.available() > 0) {
                    numBytes = inputStream.read(readBuffer);

                    if (numBytes > 0) {
                        String weight = LoadometerParser.parseDs3(readBuffer,comConfig);
                        if(!"".equals(weight)){
                               /* //去除首位的0
                             portData = weight;
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                logger.error(e.getMessage());
                            }*/
                          if(dataCache.size()<3){
                              dataCache.add(Double.valueOf(weight));
                          }else{
                              portData = NumberUtil.maxCountOfArray(dataCache).toString();
                              logger.info("读取到的串口数据为=="+portData);
                              dataCache.clear();
                          }
                            try {
                                Thread.sleep(60);
                            } catch (InterruptedException e) {
                                logger.error(e.getMessage());
                            }
                        }
                        // 重新构造缓冲对象，否则有可能会影响接下来接收的数据
                        readBuffer = new byte[20];
                    } else {
                        portData = "没有读到数据";
                    }
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
                break;
            }
            repaint();

        }
    }

    public String getPortData() {
        return portData;
    }

    public void setPortData(String portData) {
        this.portData = portData;
    }
}
